<template>
  <h3>自定义事件及emits选项</h3>

  <h4>这是父组件</h4>

  <div class="child">
    <Child @test="showTestMsg" @click="customClick"></Child>
  </div>
  <hr>

  <div @click="doTestClick" class="devclick">单击测试-点我</div>
  <span @click="doTestClick" class="spanclick">原生事件测试</span>
  <hr>

  <p>{{msg}}</p>
  <hr>

  <p>
    注意: <br>
    1. $on，$off 和 $once 实例方法已被移除，组件实例不再实现事件触发接口。<br>
    2. setup函数中,context.emit用于触发由父组件声明式添加的事件处理函数。<br>
    3. emits选项用于明确配置要触发的自定义事件.事件的native修饰符在vue3已经没用,vue3可以自动识别原生事件.<br>
    4. 一般说来,不鼓励使用全局的事件总线在组件之间进行通信。根据具体情况来看，有多种事件总线的替代方案：<br>
    &nbsp;&nbsp;&nbsp;&nbsp;1). Prop 和事件应该是父子组件之间沟通的首选。兄弟节点可以通过它们的父节点通信。<br>
    &nbsp;&nbsp;&nbsp;&nbsp;2). Provide 和 inject 允许一个组件与它的插槽内容进行通信。这对于总是一起使用的紧密耦合的组件非常有用。<br>
    &nbsp;&nbsp;&nbsp;&nbsp;3). provide/inject 也能够用于组件之间的远距离通信。它可以帮助避免“prop 逐级透传”，即 prop 需要通过许多层级的组件传递下去，但这些组件本身可能并不需要那些 prop。<br>
    &nbsp;&nbsp;&nbsp;&nbsp;4). Prop 逐级透传也可以通过重构以使用插槽来避免。如果一个中间组件不需要某些 prop，那么表明它可能存在关注点分离的问题。在该类组件中使用 slot 可以允许父节点直接为它创建内容，因此 prop 可以被直接传递而不需要中间组件的参与。<br>
    &nbsp;&nbsp;&nbsp;&nbsp;5). 使用全局状态管理，比如 Vuex。<br>
    官方文档: <a href="https://v3.cn.vuejs.org/guide/migration/emits-option.html"><b>emits选项</b></a>&nbsp;,&nbsp;
             <a href="https://v3.cn.vuejs.org/guide/migration/events-api.html"><b>事件API</b></a>
  </p>
</template>

<script>
import {ref} from 'vue'
import Child from './Child'

export default {
  components: {
    Child
  },
  setup() {
    let msg = ref('这里显示收到的消息.')

    function showTestMsg(value){
      msg.value = value
    }

    function customClick(value){
      msg.value = value
    }

    function doTestClick(event) {
      alert(`来自 "${event.target.innerHTML}" 的点击.`)
    }

    return {msg, showTestMsg, customClick, doTestClick}
  },
}
</script>

<style scoped>
  p {
    width: calc(100% -20px);
    height: 30px;
    padding: 10px;
    border: 1px solid navajowhite;
  }

  .child {
    background-color: #9be;
    padding: 2px 4px 1px 4px;
  }

  .other {
    background-color: #d9e7f4;
  }

  .devclick {
    background-color: #b9bbee;
  }

  .spanclick {
    background-color: #d9bbee;
    display: block;
    margin-top: 15px;
    margin-left: 10px;
  }

</style>